package com.avic.system.controller;

import com.avic.system.common.constant.LocalCacheConstant;
import com.avic.system.common.constant.SystemLogConstant;
import com.avic.system.common.constant.UserConstant;
import com.avic.system.common.convertor.MenuPermissionConvertor;
import com.avic.system.common.util.AssertUtil;
import com.avic.system.common.util.lang.BaseResponse;
import com.avic.system.common.util.lang.ServiceCallBack;
import com.avic.system.controller.info.MenuPermissionInfo;
import com.avic.system.controller.info.SystemPermissionInfo;
import com.avic.system.controller.request.CreateSystemPermissionReq;
import com.avic.system.controller.request.ModifySystemPermissionReq;
import com.avic.system.controller.result.CreateSystemPermissionRes;
import com.avic.system.controller.result.GetMenuPermissionRes;
import com.avic.system.controller.result.GetPermissionByRoleIdRes;
import com.avic.system.controller.result.GetSystemPermissionByMenuIdRes;
import com.avic.system.dal.model.SystemPermission;
import com.avic.system.dal.model.vo.MenuPermission;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;


@Slf4j
@RestController
@RequestMapping("/system/permission")
@Api(tags = "系统权限", description = "获取所有菜单和权限的数据&获取菜单下的权限&创建权限&修改权限&获取角色下的权限ID&删除权限接口")
public class SystemPermissionController extends AbstractFacadeImpl {

    @ApiOperation(value = "获取所有菜单联合权限的数据", notes = "权限分配页面显示接口，接口结果是递归模型，但是菜单数据只有两级")
    @GetMapping("menuPermission")
    public GetMenuPermissionRes getMenuPermission() {
        log.info("获取所有菜单联合权限的数据--getMenuPermission");
        final GetMenuPermissionRes result = new GetMenuPermissionRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {
            }

            @Override
            public void doService() throws Exception {
                if (null != LocalCacheConstant.MENU_PERMISSION_DATA_LIST && LocalCacheConstant.MENU_PERMISSION_DATA_LIST.size() > 0) {
                    log.info("从缓存中获取菜单和权限数据");
                    result.setMenuPermissionDatas(LocalCacheConstant.MENU_PERMISSION_DATA_LIST);
                } else {
                    log.info("从DB中获取数据");
                    List<MenuPermission> menuAndPermissions = systemPermissionService.getMenuPermissions();
                    List<MenuPermissionInfo> menuPermissionInfos = MenuPermissionConvertor.menuAndPermissionListToMenuPermissionInfo(menuAndPermissions);
                    result.setMenuPermissionDatas(menuPermissionInfos);
                    // 更新缓存
                    LocalCacheConstant.MENU_PERMISSION_DATA_LIST.addAll(menuPermissionInfos);
                }
                result.setSuccess(true);
            }
        });
    }

    @ApiOperation(value = "获取角色拥有的权限ID数据", notes = "用于显示角色的权限渲染")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", paramType = "path", value = "角色ID", required = true)
    })
    @GetMapping("rolePermission/{roleId}")
    public GetPermissionByRoleIdRes getPermissionByRoleId(@PathVariable("roleId") String roleId) {
        log.info("获取所有菜单联合权限的数据--getPermissionByRoleId");
        final GetPermissionByRoleIdRes result = new GetPermissionByRoleIdRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {
                AssertUtil.isNotBlank(roleId, "roleId is blank");
                log.info("获取角色ID为 {} 的权限", roleId);
            }

            @Override
            public void doService() throws Exception {
                List<String> permissionIds = systemPermissionService.getPermissionByRoleId(roleId);
                if (null != permissionIds && permissionIds.size() > 0) {
                    result.setPermissionIds(permissionIds);
                    log.info("获取到该角色的权限数量为：{}", permissionIds.size());
                }
                result.setPermissionIds(permissionIds);
                result.setSuccess(true);
            }
        });

    }

    @ApiOperation(value = "新增系统权限数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "createSystemPermissionReq", required = true, dataType = "CreateSystemPermissionReq")
    })
    @ApiResponses({
            @ApiResponse(code = 100010, message = "权限code已经存在")
    })
    @PostMapping
    public CreateSystemPermissionRes createSystemPermission(@RequestBody CreateSystemPermissionReq createSystemPermissionReq,
                                                            @RequestHeader(value = UserConstant.HEADER_CURRENT_USER_ID_KEY, required = false) String currentUserId) {
        log.info("新增系统权限数据--createSystemPermission");
        final CreateSystemPermissionRes result = new CreateSystemPermissionRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {
                AssertUtil.isNotBlank(createSystemPermissionReq.getMenuId(), "menuId is blank");
                AssertUtil.isNotBlank(createSystemPermissionReq.getPermissionCode(), "permissionCode is blank");
                AssertUtil.isNotBlank(createSystemPermissionReq.getPermissionName(), "permissionName is blank");
                AssertUtil.isNotBlank(currentUserId, "操作人不能为空");
            }

            @Override
            public void doService() throws Exception {

                SystemPermission systemPermission = new SystemPermission();
                systemPermission.setMenuId(createSystemPermissionReq.getMenuId());
                systemPermission.setPermissionCode(createSystemPermissionReq.getPermissionCode());
                systemPermission.setPermissionName(createSystemPermissionReq.getPermissionName());

                String permissionId = systemPermissionService.createSystemPermission(systemPermission);
                log.info("成功新增 ID= {} 的权限数据", permissionId);
                result.setPermissionId(permissionId);
                // 清除缓存
                LocalCacheConstant.MENU_PERMISSION_DATA_LIST.clear();
                // 新建系统日志
                systemLogService.createSystemLog(String.format(SystemLogConstant.CREATE_SYSTEM_PERMISSION_STRING, createSystemPermissionReq.getPermissionName(),
                        createSystemPermissionReq.getPermissionCode(), permissionId), currentUserId);
                result.setSuccess(true);
            }
        });
    }

    @ApiOperation(value = "更新系统权限数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "modifySystemPermissionReq", required = true, dataType = "ModifySystemPermissionReq")
    })
    @ApiResponses({
            @ApiResponse(code = 100010, message = "权限code已经存在"),
            @ApiResponse(code = 100011, message = "权限数据不存在")
    })
    @PutMapping
    public BaseResponse updateSystemPermission(@RequestBody ModifySystemPermissionReq modifySystemPermissionReq,
                                               @RequestHeader(value = UserConstant.HEADER_CURRENT_USER_ID_KEY, required = false) String currentUserId) {
        log.info("更新系统权限数据--updateSystemPermission");
        final BaseResponse result = new BaseResponse();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {

                AssertUtil.isNotBlank(modifySystemPermissionReq.getPermissionId(), "permissionId is blank");
                AssertUtil.isNotBlank(currentUserId, "操作人不能为空");
            }

            @Override
            public void doService() throws Exception {

                log.info("更新：code = {} 的权限数据", modifySystemPermissionReq.getPermissionCode());
                SystemPermission systemPermission = new SystemPermission();
                systemPermission.setId(modifySystemPermissionReq.getPermissionId());
                systemPermission.setPermissionCode(modifySystemPermissionReq.getPermissionCode());
                systemPermission.setPermissionName(modifySystemPermissionReq.getPermissionName());
                systemPermissionService.updateSystemPermission(systemPermission);

                // 清除缓存
                LocalCacheConstant.MENU_PERMISSION_DATA_LIST.clear();

                // 新建系统日志
                systemLogService.createSystemLog(String.format(SystemLogConstant.UPDATE_SYSTEM_PERMISSION_STRING, modifySystemPermissionReq.getPermissionId(),
                        modifySystemPermissionReq.getPermissionName(), modifySystemPermissionReq.getPermissionCode()), currentUserId);
                result.setSuccess(true);
            }
        });
    }

    @ApiOperation(value = "删除系统权限数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "permissionId", paramType = "path", value = "权限ID", required = true)
    })
    @DeleteMapping("/{permissionId}")
    public BaseResponse deleteSystemPermission(@PathVariable("permissionId") String permissionId,
                                               @RequestHeader(value = UserConstant.HEADER_CURRENT_USER_ID_KEY, required = false) String currentUserId) {
        log.info("删除系统权限数据--deleteSystemPermission");
        final BaseResponse result = new BaseResponse();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {
                AssertUtil.isNotBlank(permissionId, "permissionId is blank");
                AssertUtil.isNotBlank(currentUserId, "操作人不能为空");
            }

            @Override
            public void doService() throws Exception {
                log.info("删除：{} 的权限数据", permissionId);
                systemPermissionService.deleteSystemPermission(permissionId);

                // 清除缓存
                LocalCacheConstant.MENU_PERMISSION_DATA_LIST.clear();

                // 新建系统日志
                systemLogService.createSystemLog(String.format(SystemLogConstant.DELETE_SYSTEM_PERMISSION_STRING, permissionId), currentUserId);
                result.setSuccess(true);
            }
        });
    }


    @ApiOperation(value = "获取菜单下的权限数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "menuId", paramType = "path", value = "菜单ID", required = true)
    })
    @GetMapping(value = "/{menuId}")
    public GetSystemPermissionByMenuIdRes getPermissionByMenuId(@PathVariable(value = "menuId") String menuId) {
        log.info("获取某个菜单系统权限数据--getMenuPermission");
        final GetSystemPermissionByMenuIdRes result = new GetSystemPermissionByMenuIdRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {
                AssertUtil.isNotBlank(menuId, "menuId is blank");
            }

            @Override
            public void doService() throws Exception {

                List<SystemPermission> systemPermissions = systemPermissionService.getSystemPermission(menuId);
                if (null != systemPermissions && systemPermissions.size() > 0) {
                    List<SystemPermissionInfo> systemPermissionInfos = new ArrayList<>(systemPermissions.size());
                    systemPermissions.forEach(systemPermission -> {
                        SystemPermissionInfo systemPermissionInfo = new SystemPermissionInfo();
                        systemPermissionInfo.setPermissionId(systemPermission.getId());
                        systemPermissionInfo.setPermissionName(systemPermission.getPermissionName());
                        systemPermissionInfo.setPermissionCode(systemPermission.getPermissionCode());
                        systemPermissionInfos.add(systemPermissionInfo);
                    });
                    result.setPermissionData(systemPermissionInfos);
                }
                result.setSuccess(true);
            }
        });
    }
}
